package com.tanhua.server.service;

import cn.hutool.core.util.PageUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.constants.Constants;
import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.VideoApi;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Video;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VideoVo;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.Future;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 小视频业务层
 */
@Service
@Slf4j
public class SmallVideoService {
    @DubboReference
    private VideoApi videoApi;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference
    private UserInfoApi userInfoApi;

    /**
     * 发布小视频
     * videoThumbnail:视频封面文件
     * videoFile:视频文件
     */
    //@CacheEvict(value="videos",allEntries = true)  //清空缓存
    public void addVideo(MultipartFile videoThumbnail, MultipartFile videoFile) {
        log.debug("***********发布视频了**************");
        try {
            Long userId = UserHolder.getUserId();
            //1调用阿里云保存图片封面到oss
            String originalFilename = videoThumbnail.getOriginalFilename();
            String picUrl = ossTemplate.upload(originalFilename, videoThumbnail.getInputStream());
            //2调用fastdfs保存
            //2.1取出视频文件的后缀
            String videoName = videoFile.getOriginalFilename();
            String suffix = videoName.substring(videoName.lastIndexOf(".") + 1);
            StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), suffix, null);
            String videoUrl = fdfsWebServer.getWebServerUrl()+storePath.getFullPath();//00/00/xxxxx.mp4
            //3调用服务保存视频记录
            Video video = new Video();
            video.setUserId(userId);//发布视频作者id
            video.setText("峰哥跟小红的爱情故事");//文字（app没有实现  值写死了）
            video.setPicUrl(picUrl);//视频封面url地址（oss）
            video.setVideoUrl(videoUrl);//视频文件地址(fastdfs)
            videoApi.addVideo(video);
        } catch (IOException e) {
            throw new TanHuaException(ErrorResult.error());
        }
    }

    /**
     * 小视频列表
     */
    //@Cacheable(
   //         value="videos",
    //        key = "T(com.tanhua.server.interceptor.UserHolder).getUserId()+'_'+#page+'_'+#pageSize")
    public PageResult<VideoVo> findPageVideo(Long page, Long pageSize) {
        log.debug("***********视频列表分页查询了**************");
        //1. 根据key查询redis中Vids(大数据推荐系统写入结果)
        String key = Constants.VIDEOS_RECOMMEND + UserHolder.getUserId();
        String vidsStr = stringRedisTemplate.opsForValue().get(key);// 1,2,3,4,5.....
        //2. Vids存在 根据Vids查询视频列表数据
        PageResult<Video> videoPageResult = new PageResult<>();
        Long counts = 0l;//总记录数
        int redisPages = 0;
        if(StringUtils.isNotEmpty(vidsStr)){
            String[] vidsArr = vidsStr.split(",");//将字符串转为数组
            counts = Long.valueOf(vidsArr.length);
            long start = (page - 1) * pageSize;   //跳过第几条开始查询
            List<Long> vidList = Arrays.stream(vidsArr).skip(start).limit(pageSize).map(vids -> Long.valueOf(vids)).collect(Collectors.toList());
            videoPageResult = videoApi.findPageVideo(page,pageSize,vidList);
            // 算出redis总页数
            redisPages = PageUtil.totalPage(counts.intValue(), pageSize.intValue());
            videoPageResult.setPages(Long.valueOf(redisPages));
        }else {
            //3. Vids不存在 查询视频列表按时间降序
            videoPageResult = videoApi.findPageVideo(page,pageSize,null);
            counts = videoPageResult.getCounts();
        }
        List<Video> videoList = videoPageResult.getItems();
        if(CollectionUtils.isEmpty(videoList)){
            return null;
        }
        //4. 获取所有视频作者ids
        List<Long> videoUserIds = videoList.stream().map(Video::getUserId).collect(Collectors.toList());
        //5. 根据视频作者ids查询用户详情tb_userInfo
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(videoUserIds, null);
        //6. 基于视频对象 与 用户详情对象 构造Vo
        List<VideoVo> videoVoList = new ArrayList<>();
        for (Video video : videoList) {
            videoVoList.add(VideoVo.init(userInfoMap.get(video.getUserId()),video));
        }

        return new PageResult<>(page,pageSize,counts,videoVoList);
    }

    /**
     * 視頻點贊
     * @param id
     */
    public void updateVideo(ObjectId id,String path) {
        videoApi.updateVideo(id,path);
    }
}
